#Importing Data Set
ss14pusa = read.csv(file.choose(),header=TRUE)  # read csv file
ss14pusb = read.csv(file.choose(),header=TRUE)

#Libraries
require(plyr)
require(dplyr)
require(rbokeh)
require(ggplot2)
#Importing Data Set in a faster way
library(data.table)
variables=c("SEX","OCCP","WKHP","MAR","WAGP","SCHL","ESP","RAC1P","ST","PAOC","PWGTP")
ss14pusa=fread("~/Google Drive/Data for R/csv_pus/ss14pusa.csv",head=TRUE,select=variables)
ss14pusb=fread("~/Google Drive/Data for R/csv_pus/ss14pusb.csv",head=TRUE,select=variables)
attach(ss14pusa)
names(ss14pusa)
<<<<<<< HEAD
ss14pusa_edit = data.frame(SEX,OCCP,WKHP,MAR,WAGP,SCHL,ESP, RAC1P, ST, PAOC, PWGTP, AGEP)
detach(ss14pusa)

attach(ss14pusb)
ss14pusb_edit = data.frame(SEX,OCCP,WKHP,MAR,WAGP,SCHL,ESP, RAC1P, ST, PAOC, PWGTP, AGEP)
=======
ss14pusa_edit = data.frame(SEX,OCCP,WKHP,MAR,WAGP,SCHL,ESP, RAC1P, ST, PAOC, PWGTP)
detach(ss14pusa)

attach(ss14pusb)
ss14pusb_edit = data.frame(SEX,OCCP,WKHP,MAR,WAGP,SCHL,ESP, RAC1P, ST, PAOC, PWGTP)
>>>>>>> master
detach(ss14pusb)

Data = rbind(ss14pusa_edit,ss14pusb_edit)
colnames(Data) <- c("Gender","Occupation", "Work_hours", "Marriage", "Income", "Education" ,"Parental_Occupation", "Race", "State", "Children", "Weight", "Age")


write.csv(Data, file = "Data.csv",row.names=TRUE)
#Delete income=0/NA rows
row_to_keep=which(Data$Income>0)
Data=Data[row_to_keep,]
#Recode Region
#https://en.wikipedia.org/wiki/List_of_regions_of_the_United_States#/media/File:Census_Regions_and_Division_of_the_United_States.svg
<<<<<<< HEAD
Data$Region <- recode(Data$State,c(09,23,25,33,44,59,34,36,42)='Northeast';c(17,18,26,38,55,19,20,27,29,31,38,46)='Mid West'; c(10,12,13,24,37,45,51,11,54,01,21,28,47,05,22,40,48)='South';c(04,08,16,30,32,35,49,50,02,06,15,41,53)='West'))
=======
require(car)
Data$Region <- recode(Data$State,"c(09,23,25,33,44,59,34,36,42)='Northeast';c(17,18,26,38,55,19,20,27,29,31,38,46,39)='Midwest'; c(10,12,13,24,37,45,51,11,54,01,21,28,47,05,22,40,48)='South';c(04,08,16,30,32,35,49,50,02,06,15,41,53,56)='West';'72'='Puerto Rico'")
# Recode Division
Data$Division <- recode(Data$State,"c(53,41,6,2,15)='Pacific';c(4,8,16,30,32,35,49,56)='Mountain'; c(19,20,27,29,31,38,46)='West North Central';c(17,18,26,39,55)='East North Central';c(5,22,40,48)='West South Central';c(1,21,28,47)='East South Central';c(34,36,42)='Middle Atlantic';c(10,11,12,13,24,37,45,51,54)='South Atlantic';c(9,23,25,33,44,50)='New England'")

master

#Recode Education
Data$Education <- recode(Data$Education,"c(01,02,03,04,05,06,07,08,09,10,11)='~greade8';c(12,13,14,15,16,17,18,19)='grade9~college_nodegree';c(20,21)='associate/bachelor';c(22,23)='master/professional';c(24)='doctor')")

#Recode Marriage
Data$Marriage <- as.factor(Data$Marriage)
levels(Data$Marriage) <- c("Married", "Widowed", "Divorced", "Seperated", "Never Married")
#Recode Education
library(car)
Data$Education <- recode(Data$Education,"1:11='~greade8';12:19='grade9~college_nodegree';20:21='associate/bachelor';22:23='master/professional';24='doctor'")

summary(lm(MEAN ~ Marriage + Age, data = Data_wed_SCI))

Managers

Women_MGR<-filter(Data_women, Occupation ==“MGR”) Data_wed_MGR <- ddply(Women_MGR, .(Marriage, Age), summarise, MEAN = weighted.mean(Income, Weight, na.rm = T))

ggplot(Data_wed_MGR,aes(y = MEAN, x =Age,colour=Marriage,shape=Marriage)) + geom_point() + geom_smooth(method=“loess”, fill=NA)

mgr <- figure(width = NULL, height = NULL) %>% ly_points(Age, MEAN, data = Data_wed_MGR, color = Marriage, glyph = as.factor(Marriage), hover = list(Marriage, Age)) mgr

Lawyers

Women_LGL<-filter(Data_women, Occupation ==“LGL”) Data_wed_LGL <- ddply(Women_LGL, .(Marriage, Age), summarise, MEAN = weighted.mean(Income, Weight, na.rm = T))

ggplot(Data_wed_LGL,aes(y = MEAN, x =Age,colour=Marriage,shape=Marriage)) + geom_point() + geom_smooth(method=“loess”, fill=NA)

lgl <- figure(width = NULL, height = NULL) %>% ly_points(Age, MEAN, data = Data_wed_LGL, color = Marriage, glyph = as.factor(Marriage), hover = list(Marriage, Age)) lgl

summary(lm(MEAN ~ Marriage + Age, data = Data_wed_LGL))

Business

Women_BUS<-filter(Data_women, Occupation ==“BUS”) Data_wed_BUS <- ddply(Women_BUS, .(Marriage, Age), summarise, MEAN = weighted.mean(Income, Weight, na.rm = T))

ggplot(Data_wed_BUS,aes(y = MEAN, x =Age,colour=Marriage,shape=Marriage)) + geom_point() + geom_smooth(method=“loess”, fill=NA)

bus <- figure(width = NULL, height = NULL) %>% ly_points(Age, MEAN, data = Data_wed_BUS, color = Marriage, hover = list(Marriage, Age)) bus

summary(lm(MEAN ~ Marriage + Age, data = Data_wed_BUS))

Computer

Women_CMM<-filter(Data_women, Occupation ==“CMM”) Data_wed_CMM <- ddply(Women_CMM, .(Marriage, Age), summarise, MEAN = weighted.mean(Income, Weight, na.rm = T))

ggplot(Data_wed_CMM,aes(y = MEAN, x =Age,colour=Marriage,shape=Marriage)) + geom_point() + geom_smooth(method=“loess”, fill=NA)

cmm <- figure(width = NULL, height = NULL) %>% ly_points(Age, MEAN, data = Data_wed_CMM, color = Marriage, hover = list(Marriage, Age))

cmm

summary(lm(MEAN ~ Marriage + Age, data = Data_wed_CMM))

bounds <- range(c(Data_wed_occp\(Marriage, Data_wed_occp\)MEAN ))

grid_plot(lapply(split(Data_wed_occp, as.factor(Data_wed_occp$Occupation)), function(d) { figure(width = 300, height = 350) %>% ly_points(Age, MEAN, data = Data_wed_occp, color = Marriage, hover = list(Marriage, Age)) }), nrow = 2, same_axes = TRUE)

ggplot(Data_wed_occp,aes(x = factor(Occupation), fill = factor(Marriage), y = MEAN)) + geom_bar(stat = “identity”) + geom_text(position = “stack”,aes(y = MEAN, label = Marriage), size = 2, check_overlap = TRUE)

require(plotly) p <- plot_ly(Data_wed_occp, x = Age, y = MEAN,group = Occupation, text = paste(“Clarity:”, Age), mode = “markers”, xaxis = paste0(“x”, Occupation), symbol = Marriage, jitter = .9)

p<- subplot(p) ``` ???

master

MotherWorking=select(Data_women, Income,Children,Work_hours)
#detach(package:plyr)
GroupedMotherWorking <-
  MotherWorking %>%
  na.omit() %>%
  group_by(Children,Work_hours) %>% 
  summarize(
    AvgIncome = mean(Income),
    count=n()
  ) 

library(plotly)
# note how size is automatically scaled and added as hover text

plot_ly(GroupedMotherWorking, x = Work_hours, y = AvgIncome,size=sqrt(count), color = Children,text = paste("Count: ", count),opacity=1-Children*0.2,mode = "markers")

#plot_ly(GroupedMotherWorking, x = Work_hours, y = AvgIncome, text = paste("Count: ", #count),mode = "markers", opacity=1-Children*0.2,color = Children)

Observations: 1. When work_hours smaller than 60Hrs, Avg Income tend to be positively related to work hour. 2. There are generally more females with no Children 3. Females with Children from 6 to 17 often has higher avg income

ggplotly(p)

ggplotly(p)
Error in file(file, ifelse(append, "a", "w")) : 
  cannot open the connection

Observations: 1. Females with Children from 6 to 17 usually tend to have higher average income as the dot has darker color. 2. Occupation of ENG, MGR and CMM usually tend to have higher salary. On the other hand, female in LGL field always have lower salary 3.

From the graphs we see that the Northeast region, especially the New England Division, has higher income level than other parts of the States. The next question is why it happens, e.g. particular popular high-income occupations in certain regions?

LS0tCnRpdGxlOiAiV29tZW4gaW4gV29yayBGb3JjZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9IAojSW1wb3J0aW5nIERhdGEgU2V0CnNzMTRwdXNhID0gcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSxoZWFkZXI9VFJVRSkgICMgcmVhZCBjc3YgZmlsZQpzczE0cHVzYiA9IHJlYWQuY3N2KGZpbGUuY2hvb3NlKCksaGVhZGVyPVRSVUUpCgojTGlicmFyaWVzCnJlcXVpcmUocGx5cikKcmVxdWlyZShkcGx5cikKcmVxdWlyZShyYm9rZWgpCnJlcXVpcmUoZ2dwbG90MikKYGBgCgpgYGB7cn0KI0ltcG9ydGluZyBEYXRhIFNldCBpbiBhIGZhc3RlciB3YXkKbGlicmFyeShkYXRhLnRhYmxlKQp2YXJpYWJsZXM9YygiU0VYIiwiT0NDUCIsIldLSFAiLCJNQVIiLCJXQUdQIiwiU0NITCIsIkVTUCIsIlJBQzFQIiwiU1QiLCJQQU9DIiwiUFdHVFAiKQpzczE0cHVzYT1mcmVhZCgifi9Hb29nbGUgRHJpdmUvRGF0YSBmb3IgUi9jc3ZfcHVzL3NzMTRwdXNhLmNzdiIsaGVhZD1UUlVFLHNlbGVjdD12YXJpYWJsZXMpCnNzMTRwdXNiPWZyZWFkKCJ+L0dvb2dsZSBEcml2ZS9EYXRhIGZvciBSL2Nzdl9wdXMvc3MxNHB1c2IuY3N2IixoZWFkPVRSVUUsc2VsZWN0PXZhcmlhYmxlcykKCmBgYAoKYGBge3J9CmF0dGFjaChzczE0cHVzYSkKbmFtZXMoc3MxNHB1c2EpCjw8PDw8PDwgSEVBRApzczE0cHVzYV9lZGl0ID0gZGF0YS5mcmFtZShTRVgsT0NDUCxXS0hQLE1BUixXQUdQLFNDSEwsRVNQLCBSQUMxUCwgU1QsIFBBT0MsIFBXR1RQLCBBR0VQKQpkZXRhY2goc3MxNHB1c2EpCgphdHRhY2goc3MxNHB1c2IpCnNzMTRwdXNiX2VkaXQgPSBkYXRhLmZyYW1lKFNFWCxPQ0NQLFdLSFAsTUFSLFdBR1AsU0NITCxFU1AsIFJBQzFQLCBTVCwgUEFPQywgUFdHVFAsIEFHRVApCj09PT09PT0Kc3MxNHB1c2FfZWRpdCA9IGRhdGEuZnJhbWUoU0VYLE9DQ1AsV0tIUCxNQVIsV0FHUCxTQ0hMLEVTUCwgUkFDMVAsIFNULCBQQU9DLCBQV0dUUCkKZGV0YWNoKHNzMTRwdXNhKQoKYXR0YWNoKHNzMTRwdXNiKQpzczE0cHVzYl9lZGl0ID0gZGF0YS5mcmFtZShTRVgsT0NDUCxXS0hQLE1BUixXQUdQLFNDSEwsRVNQLCBSQUMxUCwgU1QsIFBBT0MsIFBXR1RQKQo+Pj4+Pj4+IG1hc3RlcgpkZXRhY2goc3MxNHB1c2IpCgpEYXRhID0gcmJpbmQoc3MxNHB1c2FfZWRpdCxzczE0cHVzYl9lZGl0KQpjb2xuYW1lcyhEYXRhKSA8LSBjKCJHZW5kZXIiLCJPY2N1cGF0aW9uIiwgIldvcmtfaG91cnMiLCAiTWFycmlhZ2UiLCAiSW5jb21lIiwgIkVkdWNhdGlvbiIgLCJQYXJlbnRhbF9PY2N1cGF0aW9uIiwgIlJhY2UiLCAiU3RhdGUiLCAiQ2hpbGRyZW4iLCAiV2VpZ2h0IiwgIkFnZSIpCgoKd3JpdGUuY3N2KERhdGEsIGZpbGUgPSAiRGF0YS5jc3YiLHJvdy5uYW1lcz1UUlVFKQpgYGAKCmBgYHtyfQojRGVsZXRlIGluY29tZT0wL05BIHJvd3MKcm93X3RvX2tlZXA9d2hpY2goRGF0YSRJbmNvbWU+MCkKRGF0YT1EYXRhW3Jvd190b19rZWVwLF0KYGBgCgpgYGB7ciwgZWNobyA9IEZBTFNFfQojcmVjb2RlIE9DQ1AKY2xhc3MoRGF0YSRPY2N1cGF0aW9uKSA8LSAibnVtZXJpYyIKRGF0YSRPY2N1cGF0aW9uIDwtIGlmZWxzZShEYXRhJE9jY3VwYXRpb24gPj0gMTAgJiBEYXRhJE9jY3VwYXRpb24gPD0gNDMwLCAxLCBEYXRhJE9jY3VwYXRpb24pCkRhdGEkT2NjdXBhdGlvbiA8LSBpZmVsc2UoRGF0YSRPY2N1cGF0aW9uID49IDEwMDUgJiBEYXRhJE9jY3VwYXRpb24gPD0gMTI0MCwgMiwgRGF0YSRPY2N1cGF0aW9uKQpEYXRhJE9jY3VwYXRpb24gPC0gaWZlbHNlKERhdGEkT2NjdXBhdGlvbiA+PSA4MDAgJiBEYXRhJE9jY3VwYXRpb24gPD0gOTUwLCAzLCBEYXRhJE9jY3VwYXRpb24pCkRhdGEkT2NjdXBhdGlvbiA8LSBpZmVsc2UoRGF0YSRPY2N1cGF0aW9uID49IDIxMDUgJiBEYXRhJE9jY3VwYXRpb24gPD0gMjE2MCwgNCwgRGF0YSRPY2N1cGF0aW9uKQpEYXRhJE9jY3VwYXRpb24gPC0gaWZlbHNlKERhdGEkT2NjdXBhdGlvbiA+PSAzMDAwICYgRGF0YSRPY2N1cGF0aW9uIDw9IDM1NDAsIDUsIERhdGEkT2NjdXBhdGlvbikKRGF0YSRPY2N1cGF0aW9uIDwtIGlmZWxzZShEYXRhJE9jY3VwYXRpb24gPj0gNTEwICYgRGF0YSRPY2N1cGF0aW9uIDw9IDc0MCwgNiwgRGF0YSRPY2N1cGF0aW9uKQpEYXRhJE9jY3VwYXRpb24gPC0gaWZlbHNlKERhdGEkT2NjdXBhdGlvbiA+PSAxMzAwICYgRGF0YSRPY2N1cGF0aW9uIDw9IDE1NjAsIDcsIERhdGEkT2NjdXBhdGlvbikKRGF0YSRPY2N1cGF0aW9uIDwtIGlmZWxzZShEYXRhJE9jY3VwYXRpb24gPj0gMTYwMCAmIERhdGEkT2NjdXBhdGlvbiA8PSAxOTY1LCA4LCBEYXRhJE9jY3VwYXRpb24pCgpEYXRhIDwtIGZpbHRlcihEYXRhLCBPY2N1cGF0aW9uICVpbiUgYygxOjgpKQpEYXRhJE9jY3VwYXRpb24gPC0gYXMuZmFjdG9yKERhdGEkT2NjdXBhdGlvbikKCmxldmVscyhEYXRhJE9jY3VwYXRpb24pIDwtIGMoJ01HUicsICdDTU0nLCAnRklOJywgJ0xHTCcsICdNRUQnICwgJ0JVUycsICdFTkcnLCAnU0NJJykKYGBgCgpgYGB7cn0KI1JlY29kZSBSZWdpb24KI2h0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xpc3Rfb2ZfcmVnaW9uc19vZl90aGVfVW5pdGVkX1N0YXRlcyMvbWVkaWEvRmlsZTpDZW5zdXNfUmVnaW9uc19hbmRfRGl2aXNpb25fb2ZfdGhlX1VuaXRlZF9TdGF0ZXMuc3ZnCjw8PDw8PDwgSEVBRApEYXRhJFJlZ2lvbiA8LSByZWNvZGUoRGF0YSRTdGF0ZSxjKDA5LDIzLDI1LDMzLDQ0LDU5LDM0LDM2LDQyKT0nTm9ydGhlYXN0JztjKDE3LDE4LDI2LDM4LDU1LDE5LDIwLDI3LDI5LDMxLDM4LDQ2KT0nTWlkIFdlc3QnOyBjKDEwLDEyLDEzLDI0LDM3LDQ1LDUxLDExLDU0LDAxLDIxLDI4LDQ3LDA1LDIyLDQwLDQ4KT0nU291dGgnO2MoMDQsMDgsMTYsMzAsMzIsMzUsNDksNTAsMDIsMDYsMTUsNDEsNTMpPSdXZXN0JykpCj09PT09PT0KcmVxdWlyZShjYXIpCkRhdGEkUmVnaW9uIDwtIHJlY29kZShEYXRhJFN0YXRlLCJjKDA5LDIzLDI1LDMzLDQ0LDU5LDM0LDM2LDQyKT0nTm9ydGhlYXN0JztjKDE3LDE4LDI2LDM4LDU1LDE5LDIwLDI3LDI5LDMxLDM4LDQ2LDM5KT0nTWlkd2VzdCc7IGMoMTAsMTIsMTMsMjQsMzcsNDUsNTEsMTEsNTQsMDEsMjEsMjgsNDcsMDUsMjIsNDAsNDgpPSdTb3V0aCc7YygwNCwwOCwxNiwzMCwzMiwzNSw0OSw1MCwwMiwwNiwxNSw0MSw1Myw1Nik9J1dlc3QnOyc3Mic9J1B1ZXJ0byBSaWNvJyIpCmBgYApgYGB7cn0KIyBSZWNvZGUgRGl2aXNpb24KRGF0YSREaXZpc2lvbiA8LSByZWNvZGUoRGF0YSRTdGF0ZSwiYyg1Myw0MSw2LDIsMTUpPSdQYWNpZmljJztjKDQsOCwxNiwzMCwzMiwzNSw0OSw1Nik9J01vdW50YWluJzsgYygxOSwyMCwyNywyOSwzMSwzOCw0Nik9J1dlc3QgTm9ydGggQ2VudHJhbCc7YygxNywxOCwyNiwzOSw1NSk9J0Vhc3QgTm9ydGggQ2VudHJhbCc7Yyg1LDIyLDQwLDQ4KT0nV2VzdCBTb3V0aCBDZW50cmFsJztjKDEsMjEsMjgsNDcpPSdFYXN0IFNvdXRoIENlbnRyYWwnO2MoMzQsMzYsNDIpPSdNaWRkbGUgQXRsYW50aWMnO2MoMTAsMTEsMTIsMTMsMjQsMzcsNDUsNTEsNTQpPSdTb3V0aCBBdGxhbnRpYyc7Yyg5LDIzLDI1LDMzLDQ0LDUwKT0nTmV3IEVuZ2xhbmQnIikKYGBgCj4+Pj4+Pj4gbWFzdGVyCgpgYGB7cn0KI1JlY29kZSBFZHVjYXRpb24KRGF0YSRFZHVjYXRpb24gPC0gcmVjb2RlKERhdGEkRWR1Y2F0aW9uLCJjKDAxLDAyLDAzLDA0LDA1LDA2LDA3LDA4LDA5LDEwLDExKT0nfmdyZWFkZTgnO2MoMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTkpPSdncmFkZTl+Y29sbGVnZV9ub2RlZ3JlZSc7YygyMCwyMSk9J2Fzc29jaWF0ZS9iYWNoZWxvcic7YygyMiwyMyk9J21hc3Rlci9wcm9mZXNzaW9uYWwnO2MoMjQpPSdkb2N0b3InKSIpCgojUmVjb2RlIE1hcnJpYWdlCkRhdGEkTWFycmlhZ2UgPC0gYXMuZmFjdG9yKERhdGEkTWFycmlhZ2UpCmxldmVscyhEYXRhJE1hcnJpYWdlKSA8LSBjKCJNYXJyaWVkIiwgIldpZG93ZWQiLCAiRGl2b3JjZWQiLCAiU2VwZXJhdGVkIiwgIk5ldmVyIE1hcnJpZWQiKQpgYGAKCmBgYHtyfQojUmVjb2RlIEVkdWNhdGlvbgpsaWJyYXJ5KGNhcikKRGF0YSRFZHVjYXRpb24gPC0gcmVjb2RlKERhdGEkRWR1Y2F0aW9uLCIxOjExPSd+Z3JlYWRlOCc7MTI6MTk9J2dyYWRlOX5jb2xsZWdlX25vZGVncmVlJzsyMDoyMT0nYXNzb2NpYXRlL2JhY2hlbG9yJzsyMjoyMz0nbWFzdGVyL3Byb2Zlc3Npb25hbCc7MjQ9J2RvY3RvciciKQpgYGAKCmBgYHtyfQojIE9uIFN1cnZleSBXZWlnaHRzCiMgaHR0cDovL3RvcGhjaXRvLmJsb2dzcG90LmNvLmF0LzIwMTQvMDQvc29jaWFsLXNjaWVuY2UtZ29lcy1yLXdlaWdodGVkLXN1cnZleS5odG1sIFdlIGFzc2lnbiBldmVyeW9uZSB0aGF0IGRpZCBtYWtlIGl0IGludG8gdGhlIHNhbXBsZSBhIHdlaWdodC4gU28gcGVvcGxlIHRoYXQgdHVybiBvdXQgdG9vIG9mdGVuIGluIHRoZSBzYW1wbGUgcmVjZWl2ZSBhIHdlaWdodCBvZiBsZXNzIHRoYW4gMS4gQW5kIHRob3NlIHRoYXQgd2Ugd2VyZSBub3QgYWJsZSB0byByZWFjaCBlbm91Z2ggb2YgYXJlIHVwd2VpZ2h0ZWQgd2l0aCBhIHdlaWdodCBsYXJnZXIgdGhhbiAxLiBSZXNwb25kZW50cyB0aGF0IGJlbG9uZyB0byBncm91cHMgdGhhdCBoYXZlIGJlZW4gc2FtcGxlZCBwZXJmZWN0bHkgcmVjZWl2ZSBhIHdlaWdodCBvZiAxLiBUaGlzIHNvbHV0aW9uIGlzIGNhbGxlZCBwb3N0LXN0cmF0aWZpY2F0aW9uLCBiZWNhdXNlIGl0IGNvbXB1dGVzIHdlaWdodHMgYmFzZWQgb24gZ3JvdXAgKG9yIHN0cmF0dW0pIGNoYXJhY3RlcmlzdGljcywgbGlrZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGFnZSBvciBnZW5kZXIgcHJvcG9ydGlvbnMuCgpyZXF1aXJlKHN1cnZleSkKRGF0YS53ID0gc3Z5ZGVzaWduKGlkcyA9IH4xLCBkYXRhID0gRGF0YSwgd2VpZ2h0cyA9IERhdGEkV2VpZ2h0KQpzdW1tYXJ5KERhdGEudykKCiMgY29tcGFyaXNvbiBvZiB0aGUgc2V4IHJhdGlvcyBpbiB0aGUgdW53ZWlnaHRlZCBhbmQgdGhlIHdlaWdodGVkIGRhdGEgZnJhbWVzOgpwcm9wLnRhYmxlKHRhYmxlKERhdGEkR2VuZGVyKSkKcHJvcC50YWJsZShzdnl0YWJsZSh+R2VuZGVyLCBkZXNpZ24gPSBEYXRhLncpKQoKIyBSdW4gdGhpcyB0byBzZWUgaG93IGl0IHdvcmtzCnRhYmxlKERhdGEkR2VuZGVyKQpzdnl0YWJsZSh+R2VuZGVyLCBkZXNpZ24gPSBEYXRhLncpCgojIFRha2UgbXkgaW50ZXJlc3RlZCB2YXJpYWJsZSAnU3RhdGUnIGFzIGFuIGV4YW1wbGUsIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHVud2VpZ2h0ZWQgYW5kIHdlaWdodGVkIHJhdGlvIGlzIHJlYWxseSBzbWFsbApwcm9wLnRhYmxlKHRhYmxlKERhdGEkU3RhdGUpKSAtIHByb3AudGFibGUoc3Z5dGFibGUoflN0YXRlLCBkZXNpZ24gPSBEYXRhLncpKQoKIyBVbHRpbWF0ZWx5LCB0aGUgZGlmZmVyZW5jZSBmb3IgZWFjaCBpbmNvbWUgbGV2ZWwgYmV0d2VlbiB1bndlaWdodGVkIGFuZCB3ZWlnaHRlZCBpcyBzbWFsbCB0b28KcHJvcC50YWJsZSh0YWJsZShEYXRhJEluY29tZSkpIC0gcHJvcC50YWJsZShzdnl0YWJsZSh+SW5jb21lLCBkZXNpZ24gPSBEYXRhLncpKQoKYGBgCgpgYGB7ciwgZWNobyA9IEZBTFNFfQojYWRkIGluIHdlaWdodHMuLi5leGFtcGxlIGNvZGUgZnJvbSBwcmV2aW91cyBwcm9qZWN0OgpyZXF1aXJlKHN1cnZleSkKCmRmMTwtc3ZyZXBkZXNpZ24odmFyaWFibGVzPXB1c19uZXdbLDE6MTNdLCAKcmVwd2VpZ2h0cz1wdXNfbmV3WywxNDo5M10sIHR5cGU9IkJSUiIsY29tYmluZWQud2VpZ2h0cz1UUlVFLAp3ZWlnaHRzPXB1c19uZXckUFdHVFApCnN1bW1hcnkoZGYxKQpzdnltZWFuKH4gV0FHUCxkZjEsIG5hLnJtID0gVCkKCiNJZiBXZSBvbmx5IHdhbnQgdG8ga25vdyB0aGUgU0UgYW5kIE1lYW4gb2YgU3RhdGlzdGljcyBJbmNvbWU/CgpwdXNfbmV3JEZPRDFQW3B1c19uZXckRk9EMVAgPT0gMzcwMiB8IHB1c19uZXckRk9EMVAgPT0gNjIxMiB8IHB1c19uZXckRk9EMVAgPT0gNjIwMl08LSJTdGF0aXN0aWNzIgpkZjwtc3Vic2V0KHB1c19uZXcsIHB1c19uZXckRk9EMVA9PSJTdGF0aXN0aWNzIikKZGYyPC1zdnJlcGRlc2lnbih2YXJpYWJsZXM9ZGZbLDE6MTNdLCAKcmVwd2VpZ2h0cz1kZlssMTQ6OTNdLCB0eXBlPSJCUlIiLGNvbWJpbmVkLndlaWdodHM9VFJVRSwKd2VpZ2h0cz1kZiRQV0dUUCkKc3VtbWFyeShkZjIpCnN2eW1lYW4ofiBXQUdQLGRmMiwgbmEucm0gPSBUKQpgYGAKCmBgYHtyLCBlY2hvID0gRkFMU0V9CgojbWVkaWFuIHdhZ2UgZm9yIGVhY2ggb2NjdXBhdGlvbiBieSBnZW5kZXIgKGp1c3QgdG8gYWNrbm93bGVkZ2UgdGhhdCB0aGVyZSAqaXMqIGEgZ2VuZGVyIGdhcCkKPDw8PDw8PCBVcGRhdGVkIHVwc3RyZWFtCj09PT09PT0KPDw8PDw8PCBIRUFECnJlcXVpcmUoZ2dwbG90MikKPT09PT09PQo+Pj4+Pj4+IFN0YXNoZWQgY2hhbmdlcwojZmFjdG9yIG1hcnJpYWdlIGFuZCBjaGFuZ2UgbGFiZWxzCgoKPj4+Pj4+PiBvcmlnaW4vbWFzdGVyCkRhdGFfc2V4X29jY3AgPC0gZGRwbHkoRGF0YSwgLihHZW5kZXIsIE9jY3VwYXRpb24pLCBzdW1tYXJpc2UsIE1FQU4gPSB3ZWlnaHRlZC5tZWFuKEluY29tZSwgV2VpZ2h0LCBuYS5ybSA9IFQpKQpnZ3Bsb3QoRGF0YV9zZXhfb2NjcCwgYWVzKHg9T2NjdXBhdGlvbiwgeT1NRUFOLCBmaWxsPWZhY3RvcihHZW5kZXIpKSkgKyAKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIscG9zaXRpb249ImRvZGdlIikgKyAKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlPSJSZFlsR24iKSArCiAgbGFicyhmaWxsPSIiKSArIAogIHlsYWIoIk1lYW4gU2FsYXJ5ICgkKSIpICsgCiAgeGxhYigiT2NjdXBhdGlvbnMiKSArIAogIGdndGl0bGUocGFzdGUoIlNhbGFyeSBDb21wYXJpc29uIGJldHdlZW4gTWVuICYgV29tZW4iKSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLCAKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAnd2hpdGUnICkpICsgCiAgdGhlbWVfZ3JleShiYXNlX3NpemUgPSAxMikKCmBgYAoKYGBge3IsIGVjaG8gPSBGQUxTRX0KI3N1YnNldCBvbiB3b21lbiwgZXhwbG9yZSBncm91cHMgb2Ygd29tZW4KRGF0YV93b21lbiA8LSBmaWx0ZXIoRGF0YSwgR2VuZGVyID09IDIpCkRhdGFfd29tZW4gPC0gZmlsdGVyKERhdGFfd29tZW4sIEFnZSA+IDIwICYgQWdlIDwgNjYpCgojUmFjZSAtIENhdGhlcmluZQojTW90aGVyaG9vZCAtIAojTWFyaXRhbCBTdGF0dXMgLSBFcmljYSAocG90ZW50aWFsbHkgYWRkIGluIHJlZ2lvbikKI1Byb3BvcnRpb24gb2YgZ3JhZHVhdGUgZGVncmVlcyBpbiBlYWNoIG9jY3VwYXRpb24/CiNSZWdpb24gLSBWaXZpZW4KCmBgYAoKYGBge3IsIGVjaG8gPSBGQUxTRX0KPDw8PDw8PCBVcGRhdGVkIHVwc3RyZWFtCj09PT09PT0KPDw8PDw8PCBIRUFECj09PT09PT0KPj4+Pj4+PiBTdGFzaGVkIGNoYW5nZXMKI21hcml0YWwgc3RhdHVzLCBzdWJzZXQgYXQgc3BlY2lmaWMgYWdlIHRvIGNvbnRyb2wgZm9yIGV4cGVyaWVuY2UKV29tZW5fNDAgPC0gc3Vic2V0KERhdGFfd29tZW4sIERhdGFfd29tZW4kQWdlID09IDQwKQpEYXRhX3dvbWVuJEFnZWdyb3VwIDwtIGN1dChhcy5udW1lcmljKERhdGFfd29tZW4kQWdlKSwgYnJlYWtzID0gYygyMCwyNSwzMCwzNSw0MCw0NSw1MCw1NSw2MCw2NSkpCgpEYXRhX3dlZF9vY2NwIDwtIGRkcGx5KERhdGFfd29tZW4sIC4oTWFycmlhZ2UsIE9jY3VwYXRpb24sIEFnZSksIHN1bW1hcmlzZSwgTUVBTiA9IHdlaWdodGVkLm1lYW4oSW5jb21lLCBXZWlnaHQsIG5hLnJtID0gVCkpCgpwbG90KERhdGFfd2VkX29jY3AkQWdlLCBEYXRhX3dlZF9vY2NwJE1FQU4pCgpzdW1tYXJ5KGxtKE1FQU4gfiBNYXJyaWFnZSArIEFnZSArIEkoQWdlXjIpKSAsIGRhdGEgPSBEYXRhX3dlZF9vY2NwKSkKCmdncGxvdChEYXRhX3dlZF9vY2NwLGFlcyh5ID0gTUVBTiwgeCA9QWdlLGNvbG91cj1NYXJyaWFnZSxzaGFwZT1NYXJyaWFnZSkpICsKZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIGZpbGw9TkEpICsgZmFjZXRfd3JhcCh+T2NjdXBhdGlvbiwgc2NhbGVzPSAiZnJlZSIpCgojRmluYW5jZQpXb21lbl9GSU48LWZpbHRlcihEYXRhX3dvbWVuLCBPY2N1cGF0aW9uID09IkZJTiIpCkRhdGFfd2VkX0ZJTiA8LSBkZHBseShXb21lbl9GSU4sIC4oTWFycmlhZ2UsIEFnZSksIHN1bW1hcmlzZSwgTUVBTiA9IHdlaWdodGVkLm1lYW4oSW5jb21lLCBXZWlnaHQsIG5hLnJtID0gVCkpCgpnZ3Bsb3QoRGF0YV93ZWRfRklOLGFlcyh5ID0gTUVBTiwgeCA9QWdlLGNvbG91cj1NYXJyaWFnZSxzaGFwZT1NYXJyaWFnZSkpICsKZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIGZpbGw9TkEpCgpmaWd1cmUod2lkdGggPSBOVUxMLCBoZWlnaHQgPSBOVUxMKSAlPiUKICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfRklOLAogICAgY29sb3IgPSBNYXJyaWFnZSwKICAgIGhvdmVyID0gbGlzdChNYXJyaWFnZSwgQWdlKSkKCnN1bW1hcnkobG0oTUVBTiB+IE1hcnJpYWdlICsgQWdlICsgSShBZ2VeMiksIGRhdGEgPSBEYXRhX3dlZF9GSU4pKQoKV29tZW5fRU5HPC1maWx0ZXIoRGF0YV93b21lbiwgT2NjdXBhdGlvbiA9PSJFTkciKQpEYXRhX3dlZF9FTkcgPC0gZGRwbHkoV29tZW5fRU5HLCAuKE1hcnJpYWdlLCBBZ2UpLCBzdW1tYXJpc2UsIE1FQU4gPSB3ZWlnaHRlZC5tZWFuKEluY29tZSwgV2VpZ2h0LCBuYS5ybSA9IFQpKQoKZ2dwbG90KERhdGFfd2VkX0VORyxhZXMoeSA9IE1FQU4sIHggPUFnZSxjb2xvdXI9TWFycmlhZ2Usc2hhcGU9TWFycmlhZ2UpKSArCmdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBmaWxsPU5BKQoKZW5nIDwtZmlndXJlKHdpZHRoID0gTlVMTCwgaGVpZ2h0ID0gTlVMTCkgJT4lCiAgbHlfbGluZXMoQWdlZ3JvdXAsIE1FQU4sIGRhdGEgPSBEYXRhX3dlZF9FTkcsCiAgICBjb2xvciA9IE1hcnJpYWdlLCBnbHlwaCA9IGFzLmZhY3RvcihBZ2UpLAogICAgaG92ZXIgPSBsaXN0KE1hcnJpYWdlLCBBZ2UpKQoKZW5nCgpsbTEgPC0gbG0oTUVBTiB+IE1hcnJpYWdlICsgQWdlICsgSShBZ2VeMiksIGRhdGEgPSBEYXRhX3dlZF9FTkcpCnN1bW1hcnkobG0xKQoKI21lZGljYWwgZmllbGQKCldvbWVuX01FRDwtZmlsdGVyKERhdGFfd29tZW4sIE9jY3VwYXRpb24gPT0iTUVEIikKRGF0YV93ZWRfTUVEIDwtIGRkcGx5KFdvbWVuX01FRCwgLihNYXJyaWFnZSwgQWdlKSwgc3VtbWFyaXNlLCBNRUFOID0gd2VpZ2h0ZWQubWVhbihJbmNvbWUsIFdlaWdodCwgbmEucm0gPSBUKSkKCmdncGxvdChEYXRhX3dlZF9NRUQsYWVzKHkgPSBNRUFOLCB4ID1BZ2UsY29sb3VyPU1hcnJpYWdlLHNoYXBlPU1hcnJpYWdlKSkgKwpnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgZmlsbD1OQSkKCm1lZCA8LSBmaWd1cmUod2lkdGggPSBOVUxMLCBoZWlnaHQgPSBOVUxMKSAlPiUKICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfTUVELAogICAgY29sb3IgPSBNYXJyaWFnZSwgZ2x5cGggPSBhcy5mYWN0b3IoTWFycmlhZ2UpLAogICAgaG92ZXIgPSBsaXN0KE1hcnJpYWdlLCBBZ2UpKQptZWQKCnN1bW1hcnkobG0oTUVBTiB+IE1hcnJpYWdlICsgQWdlLCBkYXRhID0gRGF0YV93ZWRfTUVEKSkKCiNzY2llbnRpc3QKCldvbWVuX1NDSTwtZmlsdGVyKERhdGFfd29tZW4sIE9jY3VwYXRpb24gPT0iU0NJIikKRGF0YV93ZWRfU0NJIDwtIGRkcGx5KFdvbWVuX1NDSSwgLihNYXJyaWFnZSwgQWdlKSwgc3VtbWFyaXNlLCBNRUFOID0gd2VpZ2h0ZWQubWVhbihJbmNvbWUsIFdlaWdodCwgbmEucm0gPSBUKSkKCmdncGxvdChEYXRhX3dlZF9TQ0ksYWVzKHkgPSBNRUFOLCB4ID1BZ2UsY29sb3VyPU1hcnJpYWdlLHNoYXBlPU1hcnJpYWdlKSkgKwpnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgZmlsbD1OQSkKCnNjaSA8LSBmaWd1cmUod2lkdGggPSBOVUxMLCBoZWlnaHQgPSBOVUxMKSAlPiUKICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfU0NJLAogICAgY29sb3IgPSBNYXJyaWFnZSwgZ2x5cGggPSBhcy5mYWN0b3IoTWFycmlhZ2UpLAogICAgaG92ZXIgPSBsaXN0KE1hcnJpYWdlLCBBZ2UpKQpzY2kKPDw8PDw8PCBIRUFECgpzdW1tYXJ5KGxtKE1FQU4gfiBNYXJyaWFnZSArIEFnZSwgZGF0YSA9IERhdGFfd2VkX1NDSSkpCgojTWFuYWdlcnMKV29tZW5fTUdSPC1maWx0ZXIoRGF0YV93b21lbiwgT2NjdXBhdGlvbiA9PSJNR1IiKQpEYXRhX3dlZF9NR1IgPC0gZGRwbHkoV29tZW5fTUdSLCAuKE1hcnJpYWdlLCBBZ2UpLCBzdW1tYXJpc2UsIE1FQU4gPSB3ZWlnaHRlZC5tZWFuKEluY29tZSwgV2VpZ2h0LCBuYS5ybSA9IFQpKQoKZ2dwbG90KERhdGFfd2VkX01HUixhZXMoeSA9IE1FQU4sIHggPUFnZSxjb2xvdXI9TWFycmlhZ2Usc2hhcGU9TWFycmlhZ2UpKSArCmdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBmaWxsPU5BKQoKbWdyIDwtIGZpZ3VyZSh3aWR0aCA9IE5VTEwsIGhlaWdodCA9IE5VTEwpICU+JQogIGx5X3BvaW50cyhBZ2UsIE1FQU4sIGRhdGEgPSBEYXRhX3dlZF9NR1IsCiAgICBjb2xvciA9IE1hcnJpYWdlLCBnbHlwaCA9IGFzLmZhY3RvcihNYXJyaWFnZSksCiAgICBob3ZlciA9IGxpc3QoTWFycmlhZ2UsIEFnZSkpCm1ncgoKI0xhd3llcnMKCldvbWVuX0xHTDwtZmlsdGVyKERhdGFfd29tZW4sIE9jY3VwYXRpb24gPT0iTEdMIikKRGF0YV93ZWRfTEdMIDwtIGRkcGx5KFdvbWVuX0xHTCwgLihNYXJyaWFnZSwgQWdlKSwgc3VtbWFyaXNlLCBNRUFOID0gd2VpZ2h0ZWQubWVhbihJbmNvbWUsIFdlaWdodCwgbmEucm0gPSBUKSkKCmdncGxvdChEYXRhX3dlZF9MR0wsYWVzKHkgPSBNRUFOLCB4ID1BZ2UsY29sb3VyPU1hcnJpYWdlLHNoYXBlPU1hcnJpYWdlKSkgKwpnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgZmlsbD1OQSkKCmxnbCA8LSBmaWd1cmUod2lkdGggPSBOVUxMLCBoZWlnaHQgPSBOVUxMKSAlPiUKICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfTEdMLAogICAgY29sb3IgPSBNYXJyaWFnZSwgZ2x5cGggPSBhcy5mYWN0b3IoTWFycmlhZ2UpLAogICAgaG92ZXIgPSBsaXN0KE1hcnJpYWdlLCBBZ2UpKQpsZ2wKCnN1bW1hcnkobG0oTUVBTiB+IE1hcnJpYWdlICsgQWdlLCBkYXRhID0gRGF0YV93ZWRfTEdMKSkKCgojQnVzaW5lc3MKCldvbWVuX0JVUzwtZmlsdGVyKERhdGFfd29tZW4sIE9jY3VwYXRpb24gPT0iQlVTIikKRGF0YV93ZWRfQlVTIDwtIGRkcGx5KFdvbWVuX0JVUywgLihNYXJyaWFnZSwgQWdlKSwgc3VtbWFyaXNlLCBNRUFOID0gd2VpZ2h0ZWQubWVhbihJbmNvbWUsIFdlaWdodCwgbmEucm0gPSBUKSkKCmdncGxvdChEYXRhX3dlZF9CVVMsYWVzKHkgPSBNRUFOLCB4ID1BZ2UsY29sb3VyPU1hcnJpYWdlLHNoYXBlPU1hcnJpYWdlKSkgKwpnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgZmlsbD1OQSkKCmJ1cyA8LSBmaWd1cmUod2lkdGggPSBOVUxMLCBoZWlnaHQgPSBOVUxMKSAlPiUKICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfQlVTLAogICAgY29sb3IgPSBNYXJyaWFnZSwKICAgIGhvdmVyID0gbGlzdChNYXJyaWFnZSwgQWdlKSkKYnVzCgpzdW1tYXJ5KGxtKE1FQU4gfiBNYXJyaWFnZSArIEFnZSwgZGF0YSA9IERhdGFfd2VkX0JVUykpCjw8PDw8PDwgVXBkYXRlZCB1cHN0cmVhbQoKI0NvbXB1dGVyCgo9PT09PT09CgojQ29tcHV0ZXIKCj4+Pj4+Pj4gU3Rhc2hlZCBjaGFuZ2VzCldvbWVuX0NNTTwtZmlsdGVyKERhdGFfd29tZW4sIE9jY3VwYXRpb24gPT0iQ01NIikKRGF0YV93ZWRfQ01NIDwtIGRkcGx5KFdvbWVuX0NNTSwgLihNYXJyaWFnZSwgQWdlKSwgc3VtbWFyaXNlLCBNRUFOID0gd2VpZ2h0ZWQubWVhbihJbmNvbWUsIFdlaWdodCwgbmEucm0gPSBUKSkKCmdncGxvdChEYXRhX3dlZF9DTU0sYWVzKHkgPSBNRUFOLCB4ID1BZ2UsY29sb3VyPU1hcnJpYWdlLHNoYXBlPU1hcnJpYWdlKSkgKwpnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgZmlsbD1OQSkKCmNtbSA8LSBmaWd1cmUod2lkdGggPSBOVUxMLCBoZWlnaHQgPSBOVUxMKSAlPiUKICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfQ01NLAogICAgY29sb3IgPSBNYXJyaWFnZSwKICAgIGhvdmVyID0gbGlzdChNYXJyaWFnZSwgQWdlKSkKCmNtbSAKCnN1bW1hcnkobG0oTUVBTiB+IE1hcnJpYWdlICsgQWdlLCBkYXRhID0gRGF0YV93ZWRfQ01NKSkKCmJvdW5kcyA8LSByYW5nZShjKERhdGFfd2VkX29jY3AkTWFycmlhZ2UsIERhdGFfd2VkX29jY3AkTUVBTiApKQoKZ3JpZF9wbG90KGxhcHBseShzcGxpdChEYXRhX3dlZF9vY2NwLCBhcy5mYWN0b3IoRGF0YV93ZWRfb2NjcCRPY2N1cGF0aW9uKSksIGZ1bmN0aW9uKGQpIHsKICBmaWd1cmUod2lkdGggPSAzMDAsIGhlaWdodCA9IDM1MCkgJT4lCiAgICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfb2NjcCwKICAgIGNvbG9yID0gTWFycmlhZ2UsCiAgICBob3ZlciA9IGxpc3QoTWFycmlhZ2UsIEFnZSkpCn0pLCBucm93ID0gMiwgc2FtZV9heGVzID0gVFJVRSkKCgoKcmVxdWlyZShwbG90bHkpCnAgPC0gcGxvdF9seShEYXRhX3dlZF9vY2NwLCB4ID0gQWdlLCB5ID0gTUVBTixncm91cCA9IE9jY3VwYXRpb24sIHRleHQgPSBwYXN0ZSgiQ2xhcml0eTogIiwgQWdlKSwKICAgICAgICBtb2RlID0gIm1hcmtlcnMiLCAgeGF4aXMgPSBwYXN0ZTAoIngiLCBPY2N1cGF0aW9uKSwgc3ltYm9sID0gTWFycmlhZ2UsIGppdHRlciA9IC45KQoKcDwtIHN1YnBsb3QocCkKYGBgCgoKc3VtbWFyeShsbShNRUFOIH4gTWFycmlhZ2UgKyBBZ2UsIGRhdGEgPSBEYXRhX3dlZF9TQ0kpKQoKI01hbmFnZXJzCldvbWVuX01HUjwtZmlsdGVyKERhdGFfd29tZW4sIE9jY3VwYXRpb24gPT0iTUdSIikKRGF0YV93ZWRfTUdSIDwtIGRkcGx5KFdvbWVuX01HUiwgLihNYXJyaWFnZSwgQWdlKSwgc3VtbWFyaXNlLCBNRUFOID0gd2VpZ2h0ZWQubWVhbihJbmNvbWUsIFdlaWdodCwgbmEucm0gPSBUKSkKCmdncGxvdChEYXRhX3dlZF9NR1IsYWVzKHkgPSBNRUFOLCB4ID1BZ2UsY29sb3VyPU1hcnJpYWdlLHNoYXBlPU1hcnJpYWdlKSkgKwpnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgZmlsbD1OQSkKCm1nciA8LSBmaWd1cmUod2lkdGggPSBOVUxMLCBoZWlnaHQgPSBOVUxMKSAlPiUKICBseV9wb2ludHMoQWdlLCBNRUFOLCBkYXRhID0gRGF0YV93ZWRfTUdSLAogICAgY29sb3IgPSBNYXJyaWFnZSwgZ2x5cGggPSBhcy5mYWN0b3IoTWFycmlhZ2UpLAogICAgaG92ZXIgPSBsaXN0KE1hcnJpYWdlLCBBZ2UpKQptZ3IKCiNMYXd5ZXJzCgpXb21lbl9MR0w8LWZpbHRlcihEYXRhX3dvbWVuLCBPY2N1cGF0aW9uID09IkxHTCIpCkRhdGFfd2VkX0xHTCA8LSBkZHBseShXb21lbl9MR0wsIC4oTWFycmlhZ2UsIEFnZSksIHN1bW1hcmlzZSwgTUVBTiA9IHdlaWdodGVkLm1lYW4oSW5jb21lLCBXZWlnaHQsIG5hLnJtID0gVCkpCgpnZ3Bsb3QoRGF0YV93ZWRfTEdMLGFlcyh5ID0gTUVBTiwgeCA9QWdlLGNvbG91cj1NYXJyaWFnZSxzaGFwZT1NYXJyaWFnZSkpICsKZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIGZpbGw9TkEpCgpsZ2wgPC0gZmlndXJlKHdpZHRoID0gTlVMTCwgaGVpZ2h0ID0gTlVMTCkgJT4lCiAgbHlfcG9pbnRzKEFnZSwgTUVBTiwgZGF0YSA9IERhdGFfd2VkX0xHTCwKICAgIGNvbG9yID0gTWFycmlhZ2UsIGdseXBoID0gYXMuZmFjdG9yKE1hcnJpYWdlKSwKICAgIGhvdmVyID0gbGlzdChNYXJyaWFnZSwgQWdlKSkKbGdsCgpzdW1tYXJ5KGxtKE1FQU4gfiBNYXJyaWFnZSArIEFnZSwgZGF0YSA9IERhdGFfd2VkX0xHTCkpCgoKI0J1c2luZXNzCgpXb21lbl9CVVM8LWZpbHRlcihEYXRhX3dvbWVuLCBPY2N1cGF0aW9uID09IkJVUyIpCkRhdGFfd2VkX0JVUyA8LSBkZHBseShXb21lbl9CVVMsIC4oTWFycmlhZ2UsIEFnZSksIHN1bW1hcmlzZSwgTUVBTiA9IHdlaWdodGVkLm1lYW4oSW5jb21lLCBXZWlnaHQsIG5hLnJtID0gVCkpCgpnZ3Bsb3QoRGF0YV93ZWRfQlVTLGFlcyh5ID0gTUVBTiwgeCA9QWdlLGNvbG91cj1NYXJyaWFnZSxzaGFwZT1NYXJyaWFnZSkpICsKZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIGZpbGw9TkEpCgpidXMgPC0gZmlndXJlKHdpZHRoID0gTlVMTCwgaGVpZ2h0ID0gTlVMTCkgJT4lCiAgbHlfcG9pbnRzKEFnZSwgTUVBTiwgZGF0YSA9IERhdGFfd2VkX0JVUywKICAgIGNvbG9yID0gTWFycmlhZ2UsCiAgICBob3ZlciA9IGxpc3QoTWFycmlhZ2UsIEFnZSkpCmJ1cwoKc3VtbWFyeShsbShNRUFOIH4gTWFycmlhZ2UgKyBBZ2UsIGRhdGEgPSBEYXRhX3dlZF9CVVMpKQoKI0NvbXB1dGVyCgpXb21lbl9DTU08LWZpbHRlcihEYXRhX3dvbWVuLCBPY2N1cGF0aW9uID09IkNNTSIpCkRhdGFfd2VkX0NNTSA8LSBkZHBseShXb21lbl9DTU0sIC4oTWFycmlhZ2UsIEFnZSksIHN1bW1hcmlzZSwgTUVBTiA9IHdlaWdodGVkLm1lYW4oSW5jb21lLCBXZWlnaHQsIG5hLnJtID0gVCkpCgpnZ3Bsb3QoRGF0YV93ZWRfQ01NLGFlcyh5ID0gTUVBTiwgeCA9QWdlLGNvbG91cj1NYXJyaWFnZSxzaGFwZT1NYXJyaWFnZSkpICsKZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIGZpbGw9TkEpCgpjbW0gPC0gZmlndXJlKHdpZHRoID0gTlVMTCwgaGVpZ2h0ID0gTlVMTCkgJT4lCiAgbHlfcG9pbnRzKEFnZSwgTUVBTiwgZGF0YSA9IERhdGFfd2VkX0NNTSwKICAgIGNvbG9yID0gTWFycmlhZ2UsCiAgICBob3ZlciA9IGxpc3QoTWFycmlhZ2UsIEFnZSkpCgpjbW0gCgpzdW1tYXJ5KGxtKE1FQU4gfiBNYXJyaWFnZSArIEFnZSwgZGF0YSA9IERhdGFfd2VkX0NNTSkpCgpib3VuZHMgPC0gcmFuZ2UoYyhEYXRhX3dlZF9vY2NwJE1hcnJpYWdlLCBEYXRhX3dlZF9vY2NwJE1FQU4gKSkKCmdyaWRfcGxvdChsYXBwbHkoc3BsaXQoRGF0YV93ZWRfb2NjcCwgYXMuZmFjdG9yKERhdGFfd2VkX29jY3AkT2NjdXBhdGlvbikpLCBmdW5jdGlvbihkKSB7CiAgZmlndXJlKHdpZHRoID0gMzAwLCBoZWlnaHQgPSAzNTApICU+JQogICAgbHlfcG9pbnRzKEFnZSwgTUVBTiwgZGF0YSA9IERhdGFfd2VkX29jY3AsCiAgICBjb2xvciA9IE1hcnJpYWdlLAogICAgaG92ZXIgPSBsaXN0KE1hcnJpYWdlLCBBZ2UpKQp9KSwgbnJvdyA9IDIsIHNhbWVfYXhlcyA9IFRSVUUpCgoKCmdncGxvdChEYXRhX3dlZF9vY2NwLGFlcyh4ID0gZmFjdG9yKE9jY3VwYXRpb24pLCBmaWxsID0gZmFjdG9yKE1hcnJpYWdlKSwgCnkgPSBNRUFOKSkgKwogZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICArCiAgIGdlb21fdGV4dChwb3NpdGlvbiA9ICJzdGFjayIsYWVzKHkgPSBNRUFOLCBsYWJlbCA9IE1hcnJpYWdlKSwgc2l6ZSA9IDIsIGNoZWNrX292ZXJsYXAgPSBUUlVFKQoKCnJlcXVpcmUocGxvdGx5KQpwIDwtIHBsb3RfbHkoRGF0YV93ZWRfb2NjcCwgeCA9IEFnZSwgeSA9IE1FQU4sZ3JvdXAgPSBPY2N1cGF0aW9uLCB0ZXh0ID0gcGFzdGUoIkNsYXJpdHk6ICIsIEFnZSksCiAgICAgICAgbW9kZSA9ICJtYXJrZXJzIiwgIHhheGlzID0gcGFzdGUwKCJ4IiwgT2NjdXBhdGlvbiksIHN5bWJvbCA9IE1hcnJpYWdlLCBqaXR0ZXIgPSAuOSkKCnA8LSBzdWJwbG90KHApCmBgYCA/Pz8KCj4+Pj4+Pj4gbWFzdGVyCgpgYGB7ciwgZWNobyA9IEZBTFNFfQo+Pj4+Pj4+IG9yaWdpbi9tYXN0ZXIKRGF0YV93b21lbiA8LSBmaWx0ZXIoRGF0YSwgR2VuZGVyID09IDIpCk1vdGhlckhvb2Q9c2VsZWN0KERhdGFfd29tZW4sIEluY29tZSxDaGlsZHJlbikKI2RldGFjaChwYWNrYWdlOnBseXIpCkdyb3VwZWRNb3RoZXJIb29kIDwtCiAgTW90aGVySG9vZCAlPiUKICBuYS5vbWl0KCkgJT4lCiAgZ3JvdXBfYnkoQ2hpbGRyZW4pICU+JSAKICBzdW1tYXJpemUoCiAgICBBdmdJbmNvbWUgPSBtZWFuKEluY29tZSkKICApIAoKCiMjIyBCYXIgQ2hhcnQKZ2dwbG90KEdyb3VwZWRNb3RoZXJIb29kLCBhZXMoeD1DaGlsZHJlbiwgeT1BdmdJbmNvbWUpKSArIAogIGdlb21fYmFyKGNvbG91cj0iYmxhY2siLCBmaWxsPSIjREQ4ODg4Iiwgd2lkdGg9LjUsIHN0YXQ9ImlkZW50aXR5IikgKyAKICBndWlkZXMoZmlsbD1GQUxTRSkgKwogIHhsYWIoIkNoaWxkcmVuIikgKyB5bGFiKCJNZWFuIEluY29tZSIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoNTAwMDAsNzAwMDApKSArCiAgI3NjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDQwMDAwLDcwMDAwKSxvb2IgPSByZXNjYWxlX25vbmUpICsKICBnZ3RpdGxlKCJJbmNvbWUgZm9yIE1vdGhlcmhvb2QiKQoKCgojIyMgCmBgYAoKYGBge3J9Ck1vdGhlcldvcmtpbmc9c2VsZWN0KERhdGFfd29tZW4sIEluY29tZSxDaGlsZHJlbixXb3JrX2hvdXJzKQojZGV0YWNoKHBhY2thZ2U6cGx5cikKR3JvdXBlZE1vdGhlcldvcmtpbmcgPC0KICBNb3RoZXJXb3JraW5nICU+JQogIG5hLm9taXQoKSAlPiUKICBncm91cF9ieShDaGlsZHJlbixXb3JrX2hvdXJzKSAlPiUgCiAgc3VtbWFyaXplKAogICAgQXZnSW5jb21lID0gbWVhbihJbmNvbWUpLAogICAgY291bnQ9bigpCiAgKSAKCmxpYnJhcnkocGxvdGx5KQojIG5vdGUgaG93IHNpemUgaXMgYXV0b21hdGljYWxseSBzY2FsZWQgYW5kIGFkZGVkIGFzIGhvdmVyIHRleHQKCnBsb3RfbHkoR3JvdXBlZE1vdGhlcldvcmtpbmcsIHggPSBXb3JrX2hvdXJzLCB5ID0gQXZnSW5jb21lLHNpemU9c3FydChjb3VudCksIGNvbG9yID0gQ2hpbGRyZW4sdGV4dCA9IHBhc3RlKCJDb3VudDogIiwgY291bnQpLG9wYWNpdHk9MS1DaGlsZHJlbiowLjIsbW9kZSA9ICJtYXJrZXJzIikKCiNwbG90X2x5KEdyb3VwZWRNb3RoZXJXb3JraW5nLCB4ID0gV29ya19ob3VycywgeSA9IEF2Z0luY29tZSwgdGV4dCA9IHBhc3RlKCJDb3VudDogIiwgI2NvdW50KSxtb2RlID0gIm1hcmtlcnMiLCBvcGFjaXR5PTEtQ2hpbGRyZW4qMC4yLGNvbG9yID0gQ2hpbGRyZW4pCmBgYApPYnNlcnZhdGlvbnM6CjEuIFdoZW4gd29ya19ob3VycyBzbWFsbGVyIHRoYW4gNjBIcnMsIEF2ZyBJbmNvbWUgdGVuZCB0byBiZSBwb3NpdGl2ZWx5IHJlbGF0ZWQgdG8gd29yayBob3VyLgoyLiBUaGVyZSBhcmUgZ2VuZXJhbGx5IG1vcmUgZmVtYWxlcyB3aXRoIG5vIENoaWxkcmVuCjMuIEZlbWFsZXMgd2l0aCBDaGlsZHJlbiBmcm9tIDYgdG8gMTcgb2Z0ZW4gaGFzIGhpZ2hlciBhdmcgaW5jb21lCmBgYHtyfQpNb3RoZXJPY2N1cGF0aW9uPXNlbGVjdChEYXRhX3dvbWVuLCBJbmNvbWUsQ2hpbGRyZW4sT2NjdXBhdGlvbikKI2RldGFjaChwYWNrYWdlOnBseXIpCkdyb3VwZWRNb3RoZXJPY2N1cGF0aW9uIDwtCiAgTW90aGVyT2NjdXBhdGlvbiAlPiUKICBuYS5vbWl0KCkgJT4lCiAgZ3JvdXBfYnkoQ2hpbGRyZW4sT2NjdXBhdGlvbikgJT4lIAogIHN1bW1hcml6ZSgKICAgIEF2Z0luY29tZSA9IG1lYW4oSW5jb21lKSwKICAgIGNvdW50PW4oKQogICkgCgoKcmV2YWx1ZShHcm91cGVkTW90aGVyT2NjdXBhdGlvbiRDaGlsZHJlbixjKCcxJz0nQ2hpbGRyZW4gdW5kZXIgNicsJzInPSdDaGlsZHJlbiBmcm9tIDYgdG8gMTcnLCczJz0nQ2hpbGRyZW4gdW5kZXIgNiBhbmQgYWJvdmUgNicsJzQnPSdObyBDaGlsZHJlbicpKQoKZ2dwbG90KEdyb3VwZWRNb3RoZXJPY2N1cGF0aW9uLGFlcyh4PUNoaWxkcmVuKSkrZ2VvbV9wb2ludChhZXMoeT1PY2N1cGF0aW9uLHNpemU9Y291bnQsY29sb3VyPUF2Z0luY29tZSkpK3NjYWxlX2NvbG91cl9ncmFkaWVudChsb3c9ImdyZWVuIixoaWdoPSJyZWQiKStzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPTE6NCwgbGFiZWxzPWMoIkNoaWxkcmVuIHVuZGVyIDYiLCAiQ2hpbGRyZW4gZnJvbSA2IHRvIDE3IiwgIkNoaWxkcmVuIHVuZGVyIDYgYW5kIGFib3ZlIDYiLCAiTm8gQ2hpbGRyZW4iKSkgCgojc2NhbGVfY29sb3VyX2dyYWRpZW50bihjb2xvdXJzID0gdGVycmFpbi5jb2xvcnMoMTApKQpgYGAKT2JzZXJ2YXRpb25zOgoxLiBGZW1hbGVzIHdpdGggQ2hpbGRyZW4gZnJvbSA2IHRvIDE3IHVzdWFsbHkgdGVuZCB0byBoYXZlIGhpZ2hlciBhdmVyYWdlIGluY29tZSBhcyB0aGUgZG90IGhhcyBkYXJrZXIgY29sb3IuCjIuIE9jY3VwYXRpb24gb2YgRU5HLCBNR1IgYW5kIENNTSB1c3VhbGx5IHRlbmQgdG8gaGF2ZSBoaWdoZXIgc2FsYXJ5LiBPbiB0aGUgb3RoZXIgaGFuZCwgZmVtYWxlIGluIExHTCBmaWVsZCBhbHdheXMgaGF2ZSBsb3dlciBzYWxhcnkKMy4gCgoKYGBge3IsZWNobyA9IEZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdob2xkJ30KCiMgUmVnaW9uYWwgRWZmZWN0CiMgd2FubmEga25vdyBob3cgdG8gdXNlIHN1cnZleSB3ZWlnaHRzCiMgY2FsY3VsYXRlIG1lZGlhbiBvZiB3b21lbiBpbiBlYWNoIFN0YXRlIGFuZCBwbG90IGluIG1hcHZpZXcKIyBJbnZlc3RpZ2F0ZSBpbiBPY2N1cGF0aW9uIG9yIG90aGVyIHZhdnJpYWJsZXMgdG8gc2VlIHdoeQoKRFc9RGF0YVtEYXRhJEdlbmRlcj09MiwgXQoKIyBib3hwbG90IG9mIGVhY2ggc3RhdGUvZGl2aXNpb24vcmVnaW9uIHRvIHNlZSBkaXN0cmlidXRpb24KcmVxdWlyZShwbG90bHkpCnBsb3RfbHkoRFcsIHggPSBJbmNvbWUsIGNvbG9yID0gUmVnaW9uLCB0eXBlID0gImJveCIpCnBsb3RfbHkoRFcsIHggPSBJbmNvbWUsIGNvbG9yID0gRGl2aXNpb24sIHR5cGUgPSAiYm94IikKYm94cGxvdChEVyRJbmNvbWV+RFckU3RhdGUpIAoKIyBjYWxjdWxhdGUgbWVkaWFuIG9mIHdvbWVuIGluIGVhY2ggRGl2aXNpb24vUmVnaW9uL1N0YXRlCgpyZXF1aXJlKGRwbHlyKQoKRGl2TWVkaWFuIDwtIGFnZ3JlZ2F0ZShJbmNvbWV+RGl2aXNpb24sRGF0YV93b21lbiwgbWVkaWFuKQpSZWdNZWRpYW4gPC0gYWdncmVnYXRlKEluY29tZX5SZWdpb24sRGF0YV93b21lbiwgbWVkaWFuKQpTdGF0ZU1lZGlhbiA8LSBhZ2dyZWdhdGUoSW5jb21lflN0YXRlLERXLCBtZWRpYW4pCgojIFJlY29kZSBTdGF0ZSBOYW1lcwpyZXF1aXJlKHJlYWRyKQoKc3RhdGVuYW1lcyA8LSByZWFkX2Nzdigifi9Hb29nbGUgRHJpdmUvQ29sdW1iaWEvNTI0MyBBRFMvUHJvamVjdCAxL2RhdGEvc3RhdGVuYW1lcy5jc3YiKQpuYW1lcyhTdGF0ZU1lZGlhbilbMV08LSJjb2RlIgpTdGF0ZS5NZWRpYW4gPC0gbWVyZ2UoU3RhdGVNZWRpYW4sIHN0YXRlbmFtZXMsIGJ5PSJjb2RlIikKaGVhZChTTSkKCiMgcGxvdCBzdGF0ZSBpbmNvbWUgbWVkaWFuIGluIG1hcHZpZXcKcmVxdWlyZShnb29nbGVWaXMpCm1hcDwtZ3Zpc0dlb01hcChkYXRhPVN0YXRlLk1lZGlhbiwgbG9jYXRpb252YXIgPSAibmFtZSIsIG51bXZhcj0iSW5jb21lIixvcHRpb25zPWxpc3QocmVnaW9uPSJVUyIsZGF0YU1vZGU9InJlZ2lvbnMiLHdpZHRoPSc4MDBweCcsaGVpZ3RoPSc2MDBweCcsZ3Zpcy5lZGl0b3IgPSAiSW5jb21lIE1lZGlhbiBvZiBVUyBTdGF0ZXMiLCBjb2xvcnM9IlsweEVGRURGNSwgMHhBNjRENzldIikpCnBsb3QobWFwKQoKCmBgYApGcm9tIHRoZSBncmFwaHMgd2Ugc2VlIHRoYXQgdGhlIE5vcnRoZWFzdCByZWdpb24sIGVzcGVjaWFsbHkgdGhlIE5ldyBFbmdsYW5kIERpdmlzaW9uLCBoYXMgaGlnaGVyIGluY29tZSBsZXZlbCB0aGFuIG90aGVyIHBhcnRzIG9mIHRoZSBTdGF0ZXMuIFRoZSBuZXh0IHF1ZXN0aW9uIGlzIHdoeSBpdCBoYXBwZW5zLCBlLmcuIHBhcnRpY3VsYXIgcG9wdWxhciBoaWdoLWluY29tZSBvY2N1cGF0aW9ucyBpbiBjZXJ0YWluIHJlZ2lvbnM/Cgo=